require "utils"
require "pm"
require "pins"
require "tool"
require "aLiCMD"
require "hwCMD"
require "hwIotda"
-- require "YaLiCMD"

module(..., package.seeall)

-------------------------------------------- 配置串口 --------------------------------------------
-- 保持系统处于唤醒状态，不会休眠
pm.wake("485_uart")
-- 485芯片相关设置
pmd.ldoset(15, pmd.LDO_VMMC)

local get_sig      = pins.setup(pio.P0_22)
local sig_state    = 0
local motor_state  = 0
local motor_state2 = 0
local run_time     = 0
local count_time_1 = 0
local count_time_2 = 0
local stop_count   = 0

local cmd_buf
-- 串口ID,串口读缓冲区
local uart_id      = 2
local uart_id2     = 3

-- 设置串口1参数
uart.close(uart_id)
uart.setup(uart_id, 9600, 8, uart.PAR_NONE, uart.STOP_1)
-- uart.set_rs485_oe(uart_id, pio.P0_24)
uart.on(uart_id, "receive", function() sys.publish("UART_RECEIVE") end)

-- 设置串口2参数
uart.close(uart_id2)
uart.setup(uart_id2, 9600, 8, uart.PAR_NONE, uart.STOP_1)
-- uart.set_rs485_oe(uart_id, pio.P0_24)
uart.on(uart_id2, "receive", function() sys.publish("UART_RECEIVE2") end)

-- 485读取
local function modbusRead()
    local cacheData = ""
    while true do
        local s = uart.read(uart_id, 1)
        if s == "" then
            if not sys.waitUntil("UART_RECEIVE", 10) then
                if cacheData:len() > 0 then
                    log.info("UART REC", cacheData)
                    local res = tool.Split(string.sub(cacheData, 1, -2), ":")
                    if res[1] == "S" then
                        motor_state = tonumber(res[2])
                        sys.publish("MOTOR", res[2])
                    elseif res[1] == "R" then
                        sys.publish("LEARN", res[2])
                    end
                    -- log.info("RECEIVE", cacheData)
                    -- aLiCMD.eventPost(string.toHex(cacheData))
                    cacheData = ""
                end
            end
            sys.wait(5) -- 这里一定要延时，否则会死机
        else
            cacheData = cacheData .. s
        end
        sig_state = get_sig()
        sys.publish("SIG", sig_state)
    end
end

-- 485读取
local function modbusRead2()
    local cacheData = ""
    while true do
        local s = uart.read(uart_id2, 1)
        if s == "" then
            if not sys.waitUntil("UART_RECEIVE2", 10) then
                if cacheData:len() > 0 then
                    log.info("UART2 REC", cacheData)
                    local res = tool.Split(string.sub(cacheData, 1, -2), ":")
                    if res[1] == "S" then
                        motor_state2 = tonumber(res[2])
                        sys.publish("MOTOR2", res[2])
                    elseif res[1] == "R" then
                        sys.publish("LEARN2", res[2])
                    end
                    -- log.info("RECEIVE", cacheData)
                    -- aLiCMD.eventPost(string.toHex(cacheData))
                    cacheData = ""
                end
            end
            sys.wait(5) -- 这里一定要延时，否则会死机
        else
            cacheData = cacheData .. s
        end
    end
end

-- 启动串口数据接收任务
sys.taskInit(modbusRead)
sys.taskInit(modbusRead2)

-- 设置采样时间间隔
function set485_time(str, topic, type)
    local now = nvm.get("DEV_TIME")
    nvm.set("DEV_TIME", tonumber(str))

    local r_topic = string.gsub(topic, "request", "response")
    local re = {}
    re["code"] = 200
    re["message"] = "success"
    re["data"] = {}
    re["data"]["cmdResult"] = "Time Now:" .. now .. ",Time Set:" .. str

    re["id"] = tool.miscTime()
    re["version"] = "1.0"

    if type == "L" then
        aLiOutMsg.aLiInstertMsg(r_topic, re)
    elseif type == "Y" then
        -- YaLiOutMsg.aLiInstertMsg(r_topic, re)
    end
end

-- 出厂测试，自动发送返回
function factoryTest() uart.write(uart_id, "#LINKTA#") end

function factoryTestTask(data)
    if data == "#LINKTA#" then uart.write(uart_id, "@LINKTA@") end
end

-- 每天晚上10:30网关自动重启
function daliyReboot()
    sys.taskInit(function()
        sys.wait(65000)
        math.randomseed(os.time())
        local num = math.random(1, 40)
        while true do
            local t = misc.getClock()
            if t["hour"] == 22 and t["min"] == num then
                sys.restart("TIME to REBOOT!!")
            end
            sys.wait(10000)
        end
    end)
end

local function dataCount()
    if motor_state ~= nil and sig_state ~= nil and motor_state2 ~= nil then
        if sig_state == 0 and ((motor_state > 90 and motor_state <= 100) or (motor_state2 > 90 and motor_state2 <= 100)) then
            run_time = run_time + 1
            stop_count = 0
        end
        if sig_state == 0 and motor_state > 90 and motor_state <= 100 then
            count_time_1 = count_time_1 + 1
        end
        if sig_state == 0 and motor_state2 > 90 and motor_state2 <= 100 then
            count_time_2 = count_time_2 + 1
        end

        if sig_state ~= 0 or (motor_state < 90 and motor_state2 < 90) then
            stop_count = stop_count + 1
            if stop_count > 50 then
                if run_time > 100 then
                    aLiCMD.weightPost(
                        count_time_1 * nvm.get("WEIGHT_COEFFICIENT_1") + count_time_2 * nvm.get("WEIGHT_COEFFICIENT_2"),
                        run_time)
                end
                run_time = 0
                count_time_1 = 0
                count_time_2 = 0
                stop_count = 0
            end
        end
        if run_time > 10 then
            log.info("COUNT", count_time_1,
                count_time_1 * nvm.get("WEIGHT_COEFFICIENT_1"), count_time_2,
                count_time_2 * nvm.get("WEIGHT_COEFFICIENT_2"))
        end
        if run_time > 10 then
            sys.publish("WEIGHT_COUNT", run_time/10, count_time_1/10, count_time_2/10)
        end
    end
end

function uartSend(id, data) uart.write(id, data) end

sys.subscribe("MY_UART_REC_DAT", factoryTestTask)
sys.subscribe("SECOND_STICK", dataCount)
